
#ifndef STORAGE_H
#define STORAGE_H

#include <stdint.h>
#include "stdfax.h"
#include "hash_table.h"
#include "dns_base.h"
#include "wytimer.h"



typedef struct  _packet_type{
	unsigned char label_count;
	unsigned char   domain[256];
	unsigned char *label[64];
	unsigned char label_offsets[64];
	unsigned char label_len[64];
	hash_t hash[64];
	//     uchar   origindomain[256];
} packet_type;


typedef struct _request_info request_info;
typedef struct _request_node request_node;
struct _request_node
{
	request_node *next;
	request_node *prev_chain;
	request_info *parent;
	hash_t key;
	int id;
	// cb
	packet_type lowerdomain;
	int afd;
	int hascname;
};


 struct _request_info
{
	unsigned char origin_domain[256];
	unsigned char qbuffer[256];
	packet_type lowerdomain;
	hash_t key;
	struct sockaddr_in caddr;
	request_node *node;
	request_node *cur_node;
	int type;
	int max_try;
	int stime;
	int cfd;
	int afd;
	int id;
	int qtimes;
	int hascname;
	enum rrtype qtype;
	pthread_mutex_t _lock;
	struct _request_info* next;
};


typedef struct
{
	table_t req_node_ht;
}request_node_ht;

enum
{
	_A,
	_NS,
	_CNAME,
	_AAAA,
	_MX,
	_MVALUE_TYPE_NUM,
};

enum {
	CLASS_IN = 1,
};


//used by memory hash and disk db
typedef struct {
	uint16_t len;
	uint16_t num;
	uint32_t ttl;
	uint32_t hits;
	uint32_t type;
	uint16_t per_len;
	unsigned char buff[0];
}mvalue_t;

typedef struct {
	mvalue_t* record_a;
	mvalue_t* record_ns;
	mvalue_t* records[_MVALUE_TYPE_NUM];
	unsigned  char  clean;
}record_t;


typedef struct 
{
	unsigned int buff_len;
	unsigned char buff[0];
}expire_record_t;




unsigned int get_mvalue_rdata_len(unsigned char * buff, unsigned int type);

void  ttl_expire_callback(void* per);

unsigned int take_from_expire(unsigned char * out, unsigned int out_len);

mvalue_t* create_mvalue(unsigned int len);

void append_to_mvalue(mvalue_t*val, unsigned char* buff, unsigned int len);

void insert_ns_to_dataset(dns_info_t *info);

void insert_a_to_dataset(dns_info_t*info, unsigned int start, unsigned int end);
// 
// mvalue_t* record_to_mvalues(dns_record_t* record,int *mvalue_len);

/*int add_to_record(void ** record, void * val);*/
record_t* find_record_from_dataset(unsigned char * key);
mvalue_t* find_value_from_dataset(unsigned char*key,uint32_t type);

int insert_k_v_to_dataset(unsigned char*key,unsigned char*val);

int insert_value_to_dataset(unsigned char * key, mvalue_t* val);

void init_request_info(dns_info_t *src, request_info *rinfo);

void init_request_node(request_node *ninfo);

unsigned int get_dns_type(unsigned int mvalue_type);

unsigned int get_mvalue_type(unsigned int dns_type);


void init_request_info_dnspod(request_info *rinfo);
record_t* find_record_from_temp(unsigned char * key);

#endif